package leeon.forpeddy.download;

import ipworks.Http;
import ipworks.HttpConnectedEvent;
import ipworks.HttpConnectionStatusEvent;
import ipworks.HttpDisconnectedEvent;
import ipworks.HttpEndTransferEvent;
import ipworks.HttpErrorEvent;
import ipworks.HttpEventListener;
import ipworks.HttpHeaderEvent;
import ipworks.HttpRedirectEvent;
import ipworks.HttpSetCookieEvent;
import ipworks.HttpStartTransferEvent;
import ipworks.HttpStatusEvent;
import ipworks.HttpTransferEvent;
import ipworks.IPWorksException;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.TooManyListenersException;

import leeon.util.PropertyLoader;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class HtmlDownloader {
	
	private static Log logger = LogFactory.getLog(HtmlDownloader.class);
	
	private static String PROXY_SITE = "10.10.200.8";
	private static int PROXY_PORT = 8080;
	private static String PROXY_USER = "yxliu";
	private static String PROXY_PSWD = "98180749";
	private static boolean PROXY_ENABLE = true;
	private static int RETRY = 2;
	static {
		try {
			PropertyLoader pl = PropertyLoader.newInstance("downloader.conf");
			PROXY_SITE = (pl.getProperty("proxy.site")!=null)?pl.getProperty("proxy.site"):null;
			PROXY_PORT = Integer.parseInt(pl.getProperty("proxy.port", "8080"));
			PROXY_USER = (pl.getProperty("proxy.user")!=null)?pl.getProperty("proxy.user"):null;
			PROXY_PSWD = (pl.getProperty("proxy.pswd")!=null)?pl.getProperty("proxy.pswd"):null;
			PROXY_ENABLE = ("true".equals(pl.getProperty("proxy.enable")));
			
			RETRY = Integer.parseInt(pl.getProperty("download.retry", "10"));
		} catch (Exception e) {
			logger.info("no downloader config loaded, use default download config");
		}
	}
	
	private Http http = new Http();	
	ByteArrayOutputStream content = new ByteArrayOutputStream();
	
	
	public HtmlDownloader() throws IPWorksException, TooManyListenersException {
		
		if (PROXY_ENABLE) {
			http.setProxyServer(PROXY_SITE);
			http.setProxyPort(PROXY_PORT);
			if (PROXY_USER != null) http.setProxyUser(PROXY_USER);
			if (PROXY_PSWD != null) http.setProxyPassword(PROXY_PSWD);
		}
		http.setFollowRedirects(1);
		http.addHttpEventListener(new HttpEventListener() {
			public void connected(HttpConnectedEvent arg0) {}
			public void connectionStatus(HttpConnectionStatusEvent arg0) {}
			public void disconnected(HttpDisconnectedEvent arg0) {}
			public void endTransfer(HttpEndTransferEvent arg0) {}
			public void error(HttpErrorEvent arg0) {}
			public void header(HttpHeaderEvent arg0) {}
			public void redirect(HttpRedirectEvent arg0) {}
			public void setCookie(HttpSetCookieEvent arg0) {
				try {
					http.addCookie(arg0.name, arg0.value);
				} catch (IPWorksException e) {
					logger.error("add server cookie info error", e);
				}
			}
			public void startTransfer(HttpStartTransferEvent arg0) {}
			public void status(HttpStatusEvent arg0) {}
			public void transfer(HttpTransferEvent arg0) {
				try {
					content.write(arg0.text);
				} catch (IOException e) {
					logger.error("put in content io error", e);
				}
			}
			
		});
	}
	
	
	public void start(String url) {
		int i = 0;
		while (i++ < RETRY) {
			try {
				logger.info("download url:[" + url +"] and retry " + i);
				http.get(url);
				i = RETRY;
			} catch (IPWorksException e) {
				logger.error("ipworks connect to network error, would retry...", e);
			} catch (Exception e) {
				logger.error("other runtime error, would retry...", e);
			}
		}
	}
	
	public void saveToFile(File file) throws IOException {
		logger.info("save html files to [" + file.getAbsoluteFile() + "]");
		FileOutputStream fos = new FileOutputStream(file);
		fos.write(this.content.toByteArray());
		fos.close();
		this.content.reset();
	}
	
	public String contentToString() {
		logger.info("transfer conten to String");
		String ret = new String(this.content.toByteArray());
		this.content.reset();
		return ret;
	}
	
	public void destroy() throws IOException {
		this.content.close();
	}
	
	public void login(String url) throws IOException {
		try {
			http.get(url);
			this.content.reset();
		} catch (IPWorksException e) {
			logger.error("ipworks connect to network error, would retry...", e);
		} catch (Exception e) {
			logger.error("other runtime error, would retry...", e);
		}
	}
	
	/**
	 * @param args
	 * @throws TooManyListenersException 
	 * @throws IPWorksException 
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IPWorksException, TooManyListenersException, IOException {
		HtmlDownloader h = new HtmlDownloader();
		h.start("http://218.1.69.105/acad/student/exportExcel.jsp?major=222&classNo=7059020101");
		h.saveToFile(new File("7059020101.html"));
	}
}
